import protobuf from 'protobufjs';
import Long from 'long';  // 仍然需要引入 Long 库用于验证阶段
// 如果 Nodejs 版本低于 17.5, JSON 模块导入需要另外找替代方法
import personJson from './proto/proto.json' assert { type: 'json' };

// 1. 加载编译后的 JSON 描述符
const root = protobuf.Root.fromJSON(personJson);

// 2. 获取消息类型
const Person = root.lookupType("Person");

// 3. 准备数据 - 在验证阶段使用 Long
const personDataRaw = {
  name: "Alice",
  id: "123456789012345", // 原始字符串格式
  phones: ["123-4567", "987-6543"],
  createTime: Date.now() // 数字时间戳
};

// 处理数据，将字符串 id 转换为 Long，以通过验证
const personData = {
  ...personDataRaw,
  id: Long.fromString(personDataRaw.id),     // 使用 Long 表示 id
  createTime: Long.fromNumber(personDataRaw.createTime) // 使用 Long 表示时间戳
};

// 4. 验证数据合法性
const errMsg = Person.verify(personData);
if (errMsg) throw new Error(errMsg);

// 5. 创建有效消息实例
const person = Person.create(personData);

// 6. 序列化为二进制
const buffer = Person.encode(person).finish();
console.log("Serialized Buffer:", buffer);

// 7. 反序列化
const decoded = Person.decode(buffer);
// 创建一个toObject配置，确保id作为字符串返回
const toObjectOptions = {
  longs: String, // 将所有int64/uint64转换为字符串
  defaults: true, // 包含默认值
  oneofs: true    // 包含虚拟oneof字段
};
// console.log("Deserialized Object (default):", Person.toObject(decoded));
console.log("Deserialized Object (with options):", Person.toObject(decoded, toObjectOptions));

// 现在可以安全地使用 id 和 createTime，它们都是字符串类型
const decodedObj = Person.toObject(decoded, toObjectOptions);
// 确保createTime是数字类型
decodedObj.createTime = Number(decodedObj.createTime);
console.log("decodedObj Processed Object:", decodedObj);
